package com.base.interceptor;

import java.io.IOException;
import java.net.URLEncoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.base.conf.RedisHelper;
import com.base.controller.BaseController;
import com.base.utils.CookieUtil;
import com.base.vo.LoginUserInfo;
import com.base.vo.NullObject;
import com.base.vo.Response;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * @类描述：登录检验拦截器
 * @创建人：wangdw
 * @创建时间：2018年11月1日 下午4:02:31
 * @版权：Copyright (c) 四川临港物流信息服务股份有限公司-版权所有.
 */
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    // @Autowired
    private RedisHelper redisHelper;
    
    /**
     * 是否控制权限标记
     */
    @Value("${common.isPermissionFlag:true}")
    private boolean isPermissionFlag;
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String token = CookieUtil.getCookie(request, BaseController.TOKEN_COOKIE_NAME);
        if (StringUtils.isBlank(token)) {
            logger.info("未获取到用户Cookie信息，跳转到登录页面");
            this.toLogin(request, response);
            return false;
        }
        LoginUserInfo userInfo = new LoginUserInfo();// (LoginUserInfo)
                                                     // redisHelper.get(BaseController.USER_KEY +
                                                     // token);
        if (userInfo == null) {
            logger.info("未获取到用户信息，可能缓存已过期，跳转到登录页面");
            this.toLogin(request, response);
            return false;
        }
        // redisHelper.expire(BaseController.USER_KEY + token, 60 * 30);// 延期30分钟
        logger.info("{}访问{}", userInfo.getUserName(), request.getRequestURI());
        
        // 权限控制 TODO 根据自己的系统特色实现
        boolean isPermission = isPermissionFlag ? isPermission(handler, null) : true;
        if (!isPermission) {
            toNoPermission(request, response);
            return false;
        }
        return true;
    }
    
    /**
     * 方法描述：判断当前用户是否有操作权限
     * @param handler
     * @param permissions
     * @return
     */
    private boolean isPermission(Object handler, Object permissions) {
        
        return false;
    }
    
    /**
     * 方法描述：跳转到登录页面
     * @param request
     * @param response
     * @throws IOException
     */
    private void toLogin(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 判断是否为Ajax请求
        String requestType = request.getHeader("X-Requested-With");
        if ("XMLHttpRequest".equalsIgnoreCase(requestType)) {
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
            Response<NullObject> res = new Response<>(HttpServletResponse.SC_UNAUTHORIZED, URLEncoder.encode("请登录！", "utf-8"));
            response.getWriter().write(new ObjectMapper().writeValueAsString(res));
        } else {// 非Ajax
            // 组装登录后的回调参数
            String requestUri = request.getRequestURI();
            String param = request.getQueryString();
            if (StringUtils.isNotBlank(param)) {
                requestUri += "?" + param;
            }
            logger.debug("requestUri={}", requestUri);
            requestUri = URLEncoder.encode(requestUri, "utf-8");
            response.sendRedirect(request.getContextPath() + "/login?redirect=" + requestUri);
        }
    }
    
    /**
     * 方法描述：跳转到错误页面
     * @param request
     * @param response
     * @throws IOException
     */
    private void toError(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 判断是否为Ajax请求
        String requestType = request.getHeader("X-Requested-With");
        if ("XMLHttpRequest".equalsIgnoreCase(requestType)) {
            response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
            Response<NullObject> res = new Response<>(HttpServletResponse.SC_SERVICE_UNAVAILABLE, "系统繁忙，请稍候...");
            response.getWriter().write(new ObjectMapper().writeValueAsString(res));
        } else {// 非Ajax
            String errorMsg = URLEncoder.encode("系统繁忙，请稍候...", "utf-8");
            response.sendRedirect(request.getContextPath() + "/error?errorMsg=" + errorMsg);
        }
    }
    
    /**
     * 方法描述：跳转到无权限页面
     * @param request
     * @param response
     * @throws IOException
     */
    private void toNoPermission(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 判断是否为Ajax请求
        String requestType = request.getHeader("X-Requested-With");
        if ("XMLHttpRequest".equalsIgnoreCase(requestType)) {
            response.setStatus(HttpServletResponse.SC_FORBIDDEN);
            Response<NullObject> res = new Response<>(HttpServletResponse.SC_FORBIDDEN, URLEncoder.encode("您没有相关权限", "utf-8"));
            response.getWriter().write(new ObjectMapper().writeValueAsString(res));
        } else {// 非Ajax
            String errorMsg = URLEncoder.encode("您没有相关权限", "utf-8");
            response.sendRedirect(request.getContextPath() + "/error?errorMsg=" + errorMsg);
        }
    }
}
